﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Forms;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
using System.Drawing;
using Xceed.Wpf.AvalonDock.Layout;
using ISTKPlugin;
using System.Diagnostics;
using System.IO;

namespace BDSim
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            VM.Parent = this; //给VM定义父级对象
        }

        #region 窗体加载函数
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            VM.Scenario = new Scenario();
            BDSimObject.DisplayObjectProperty = DispalyProperty;
            MainDispatcher.MainWindowDispatcher = this.Dispatcher;
            MainDispatcher.DlgAddLayoutDocument = AddItemToADockMainView;
            //LoadSTKPlugin();    
            ShowStartWizardWnd();      
        }
        #endregion

        #region 对象属性参数显示与配置控制
        /// <summary>
        /// 显示选择的模型属性参数
        /// </summary>
        /// <param name="selectedObject"></param>
        void DispalyProperty(object selectedObject)
        {
            WpfPropertyGrid1.SelectedObject = selectedObject;
            //当系统处于运行状态中时，无法修改模型属性
            if (BDSimObject.GlobalStatus != ESimStatus.UnInited && BDSimObject.GlobalStatus != ESimStatus.End)
            {
                Type readonlyType = typeof(System.ComponentModel.ReadOnlyAttribute);
                PropertyDescriptorCollection props = TypeDescriptor.GetProperties(WpfPropertyGrid1.SelectedObject);
                FieldInfo fld = readonlyType.GetField("isReadOnly", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.CreateInstance);
                AttributeCollection attrs = TypeDescriptor.GetAttributes(WpfPropertyGrid1.SelectedObject);
                fld.SetValue(attrs[typeof(ReadOnlyAttribute)], true);
            }
            else
            {
                Type readonlyType = typeof(System.ComponentModel.ReadOnlyAttribute);
                PropertyDescriptorCollection props = TypeDescriptor.GetProperties(WpfPropertyGrid1.SelectedObject);
                FieldInfo fld = readonlyType.GetField("isReadOnly", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.CreateInstance);
                AttributeCollection attrs = TypeDescriptor.GetAttributes(WpfPropertyGrid1.SelectedObject);
                fld.SetValue(attrs[typeof(ReadOnlyAttribute)], false);
            }
        }

        /// <summary>
        /// WpfPropertyGrid1选择对象更改事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void propertyGrid_flow_SelectedObjectsChanged(object sender, EventArgs e)
        {
            WpfPropertyGrid1.Tag = WpfPropertyGrid1.PropertySort;
            WpfPropertyGrid1.PropertySort = PropertySort.CategorizedAlphabetical;
            WpfPropertyGrid1.Paint += new PaintEventHandler(propertyGrid_flow_Paint);      
        }

        /// <summary>
        /// WpfPropertyGrid1控件重绘事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void propertyGrid_flow_Paint(object sender, PaintEventArgs e)
        {
            var categorysinfo = WpfPropertyGrid1.SelectedObject.GetType().GetField("categorys", BindingFlags.NonPublic | BindingFlags.Instance);
            if (categorysinfo != null)
            {
                var categorys = categorysinfo.GetValue(WpfPropertyGrid1.SelectedObject) as List<String>;
                WpfPropertyGrid1.CollapseAllGridItems();
                GridItemCollection currentPropEntries = WpfPropertyGrid1.GetType().GetField("currentPropEntries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(WpfPropertyGrid1) as GridItemCollection;
                var newarray = currentPropEntries.Cast<GridItem>().OrderBy((t) => categorys.IndexOf(t.Label)).ToArray();
                currentPropEntries.GetType().GetField("entries", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(currentPropEntries, newarray);
                WpfPropertyGrid1.ExpandAllGridItems();
                WpfPropertyGrid1.PropertySort = (PropertySort)WpfPropertyGrid1.Tag;
            }
            WpfPropertyGrid1.Paint -= new PaintEventHandler(propertyGrid_flow_Paint);
        }
        #endregion

        #region 添加新的LayoutDocument到主显示窗口

        /// <summary>
        /// 添加新的LayoutDocument到主显示窗口
        /// </summary>
        /// <param name="content"></param>
        void AddItemToADockMainView(ILayoutContent content, string title)
        {
            LayoutDocument layoutDocument = new LayoutDocument();
            layoutDocument.DlgCloseFeedBack = content.ReleaseData;
            layoutDocument.Title = title;
            layoutDocument.Content = content;

            ADockMainViewPort2.Children.Add(layoutDocument);
            int count = ADockMainViewPort2.ChildrenCount;
            ADockMainViewPort2.SelectedContentIndex = count - 1;
        }

        #endregion

        #region 控制窗口的显示隐藏

        public void ScenarioViewable()
        {
            bool flag = ADockSimScenarioView.IsVisible;
            ADockSimScenarioView.IsVisible = !flag;
        }
        public void PropertyViewable()
        {
            bool flag = ADockPropertyView.IsVisible;
            ADockPropertyView.IsVisible = !flag;
        }
        public void SysMsgViewable()
        {
            bool flag = ADockSysMessage.IsVisible;
            ADockSysMessage.IsVisible = !flag;
        }

        public void _3DViewable()
        {
            if (ADock3DView.Parent != null)
            {
                (ADock3DView.Parent as LayoutDocumentPane).Children.Remove(ADock3DView);
            }
            else if (ADock3DView.Parent != null && ADock3DView.Parent is LayoutDocumentFloatingWindow)
            {
                (ADock3DView.Parent as LayoutDocumentFloatingWindow).RemoveChild(ADock3DView);
                ADock3DView.Parent = null;
            }
            else
            {
                if (ADockMainViewPort1.Parent == null)
                {
                    mainDocument.Children.Add(ADockMainViewPort1);
                }
                ADockMainViewPort1.Children.Add(ADock3DView);
                ADockMainViewPort1.SelectedContentIndex = ADockMainViewPort1.Children.Count - 1;
            }
        }

        public void _2DViewable()
        {
            if (ADock2DView.Parent != null && ADock2DView.Parent is LayoutDocumentPane)
            {
                (ADock2DView.Parent as LayoutDocumentPane).Children.Remove(ADock2DView);
            }
            else if (ADock2DView.Parent != null && ADock2DView.Parent is LayoutDocumentFloatingWindow)
            {
                (ADock2DView.Parent as LayoutDocumentFloatingWindow).RemoveChild(ADock2DView);
                ADock2DView.Parent = null;
            }
            else
            {
                if (ADockMainViewPort1.Parent == null)
                {
                    mainDocument.Children.Add(ADockMainViewPort1);
                }
                ADockMainViewPort1.Children.Add(ADock2DView);
                ADockMainViewPort1.SelectedContentIndex = ADockMainViewPort1.Children.Count - 1;
            }
        }

        public void ADockPPositioningViewable()
        {
            if (ADockPPositioning.Parent != null)
            {
                (ADockPPositioning.Parent as LayoutDocumentPane).Children.Remove(ADockPPositioning);
            }
            else if (ADockPPositioning.Parent != null && ADockPPositioning.Parent is LayoutDocumentFloatingWindow)
            {
                (ADockPPositioning.Parent as LayoutDocumentFloatingWindow).RemoveChild(ADockPPositioning);
                ADockPPositioning.Parent = null;
            }
            else
            {
                if (ADockMainViewPort2.Parent == null)
                {
                    mainDocument.Children.Add(ADockMainViewPort2);
                }
                ADockMainViewPort2.Children.Add(ADockPPositioning);
                ADockMainViewPort2.SelectedContentIndex = ADockMainViewPort2.Children.Count - 1;
            }
        }
        #endregion

        private void BDSim_Closing(object sender, CancelEventArgs e)
        {
            bool IsCancel = false;//窗口关闭取消标志，初始为false
            switch (BDSimObject.GlobalStatus)
            {
                case ESimStatus.UnInited:

                case ESimStatus.End:
                    if (!(System.Windows.MessageBox.Show("确定退出系统？", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Information) == MessageBoxResult.OK))
                    {
                        IsCancel = true;

                        string FileName = Directory.GetCurrentDirectory() + "\\Resources\\Doc\\BDSim用户手册.pdf";
                       
                    }
                    break;
                case ESimStatus.Initing:
                case ESimStatus.Inited:
                case ESimStatus.Run:
                case ESimStatus.Pause:
                    IsCancel = true;
                    System.Windows.MessageBox.Show("系统正在运行，无法关闭！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                    break;
                default:
                    break;
            }
            e.Cancel = IsCancel;//判断窗口关闭取消标志是否为true
        }

        #region //启动向导相关内容
        /// <summary>
        /// 软件自动启动向导窗口
        /// </summary>
        private void ShowStartWizardWnd()
        {

            //if (Properties.Settings.Default.IsShowStartWizard)
            //{
                StartWizard();
                this.Focusable = true;
                this.Focus();
            //}
        }

        /// <summary>
        /// 手动启动用户向导
        /// </summary>
        private void StartWizardWnd()
        {
            StartWizard();
            this.Focusable = true;
            this.Focus();
        }

        /// <summary>
        /// 开始向导
        /// </summary>
        private void StartWizard()
        {
            StartWizardWnd startWizardWnd = new StartWizardWnd();
            startWizardWnd.Owner = this;
            startWizardWnd.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
            if (startWizardWnd.ShowDialog() == true)
            {
                switch (startWizardWnd.UserSelectIndex)
                {
                    case 1:
                        NewScenario(startWizardWnd);
                        this.Focusable = true;
                        this.Focus();
                        break;
                    case 2:
                        OpenScenario(startWizardWnd);
                        this.Focusable = true;
                        this.Focus();
                        break;
                    case 3:
                        OpenDemos(startWizardWnd);
                        this.Focusable = true;
                        this.Focus();
                        break;
                    case 4:
                        this.Close();
                        break;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// 打开教学案例
        /// </summary>
        /// <param name="startWizardWnd"></param>
        private void OpenDemos(StartWizardWnd startWizardWnd)
        {
            string FileName = Directory.GetCurrentDirectory() + "\\Resources\\Doc\\BDSim基础应用实验手册.pdf";
            Process.Start(FileName);
        }

        /// <summary>
        /// 打开仿真场景
        /// </summary>
        /// <param name="startWizardWnd"></param>
        private void OpenScenario(StartWizardWnd startWizardWnd)
        {
            //如果没有打开仿真场景则返回到开始向导
            if (!VM.OpenScenarioFile())
            {
                StartWizard();
            }
        }

        /// <summary>
        /// 新建仿真场景
        /// </summary>
        /// <param name="startWizardWnd"></param>
        private void NewScenario(StartWizardWnd startWizardWnd)
        {
            if (!VM.Scenario.DataProvider.ParamConfig())
            {
                StartWizard();
            }
        }

        
        /// <summary>
        /// 加载STK插件
        /// </summary>
        public void LoadSTKPlugin()
        {
            try
            {
                Scenario.stkPluginList.Add(controlName(VM.PluginList[0].FilePath));
                if (Scenario.stkPluginList != null)
                {
                    VM.Scenario.STKFlag= true;
                    LayoutDocument STKView = new LayoutDocument();
                    STKView.Title = "STK可视化";
                    ADockMainViewPort1.InsertChildAt(2, STKView);
                    System.Windows.Controls.Control stkGlobalView = (System.Windows.Controls.Control)(Scenario.stkPluginList[0]);
                    STKView.Content = stkGlobalView;
                }
                else
                {
                    VM.Scenario.STKFlag = false;
                }
            }
            catch (Exception exp)
            {
                //throw;
            }
            
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        InterfaceSTKPlugin controlName(string filename)
        {
            try
            {
                Type type = null;
                // 获取程序集
                Assembly asm = Assembly.LoadFrom(filename);
                foreach (Type t in asm.GetTypes())
                {
                    //搜索Itools接口，查看是否有与接口匹配的项
                    if (t.GetInterface("InterfaceSTKPlugin") != null)
                    {
                        type = t;
                        break;
                    }
                }
                //把继承Itools接口的类实例化并转换为Itools类型
                if (type != null)
                {
                    ConstructorInfo info = null;
                    InterfaceSTKPlugin toolCOM = null;
                    try
                    {
                        info = type.GetConstructor(new Type[] { });
                        object result = info.Invoke(new Object[] { });
                        toolCOM = (InterfaceSTKPlugin)result;
                    }
                    catch(Exception exp)
                    {

                    }
                    return toolCOM;
                }
                return null;
            }
            catch
            { return null; }
        }

        #endregion
    }
}
